Release 10.1A: OpenEdge Development:
ProDataSets


Caching complex derived data in a ProDataSet

As you saw in the temp-table definitions, there are calculated fields in the SalesRep temp-table. We need a procedure called postRepRowFill to generate those calculated fields. To be sure, the calculations aren’t very complex in this case, but we use this as a placeholder for a more serious application where a table of complex data that is relatively expensive to derive is loaded into a ProDataSet once so that it can be used throughout a session.

There are various alternatives to this approach. If the derived data is common to all use cases, then it can be calculated once each time the data it depends on is changed, for example, by database trigger procedure code, and stored in permanent database tables of its own. But in many cases the calculations are specific to the immediate user of the data. For example, a price sheet might depend on various factors that change from session to session, including who the current Customer is, who the user is, what the nature of the product requirements are, and so forth. In a case like this, a ProDataSet instance can provide reusable calculations that can be kept available for the user’s session or until a different Customer or product line is selected. This example illustrates such a case.

As with all FILL event procedures, this receives the ProDataSet as an INPUT parameter, passed by reference. There are also several local variables, as shown:

PROCEDURE postRepRowFill: 
    DEFINE INPUT PARAMETER DATASET-HANDLE phDataSet. 
    DEFINE VARIABLE hSalesRep     AS HANDLE     NO-UNDO. 
    DEFINE VARIABLE dTotalQuota   AS DECIMAL    NO-UNDO. 
    DEFINE VARIABLE dTotalBalance AS DECIMAL    NO-UNDO. 
    DEFINE VARIABLE iMonth        AS INTEGER    NO-UNDO. 

The ProDataSet supports several different code tables. You need to get the handle to the SalesRep table, as shown:

hSalesRep = phDataSet:GET-BUFFER-HANDLE("ttSalesRep"). 

Design tip: It’s a good idea to keep any references to the specifics of the ProDataSet structure like this as flexible as possible. In this case, the ttSalesRep table is the first one in the ProDataSet, but referencing it as GET-BUFFER-HANDLE(1) can give you maintenance headaches as definitions change. Also you might find yourself able to reuse parts of this code with a very different ProDataSet structure if you don’t assume any dependencies that you don’t need to. In some cases even the table name could be a parameter.

The first calculated field is the total Annual Quota for each SalesRep. To calculate this, you total the 12 elements of the MonthQuota array, as shown:

DO iMonth = 1 TO 12: 
    dTotalQuota = dTotalQuota + SalesRep.MonthQuota[iMonth]. 
END. 
     
hSalesRep:BUFFER-FIELD("AnnualQuota"):BUFFER-VALUE = dTotalQuota. 

Remember that because the temp-table definitions aren’t included, you need to reference the fields dynamically through the buffer handle. You need to decide when this makes the code too complex without sufficient benefit of flexibility.

Next, you calculate the Total Balance of all the SalesRep’s Customers:

FOR EACH Customer WHERE Customer.SalesRep =  
        STRING(hSalesRep:BUFFER-FIELD("RepCode"):BUFFER-VALUE): 
        dTotalBalance = dTotalBalance + Customer.Balance. 
END. 
hSalesRep:BUFFER-FIELD("TotalBalance"):BUFFER-VALUE = dTotalBalance. 
END PROCEDURE. /* postRepRowFill */ 

The other entry points are functions that attach and detach the ProDataSets. The attachDataSet function takes the ProDataSet handle as an INPUT parameter, sets the callback procedure for the AFTER-ROW-FILL event for the ttSalesRep table, and attaches the Data-Sources, as shown:

FUNCTION attachDataSet RETURNS LOGICAL  
    (INPUT phDataSet AS HANDLE): 
      
    phDataSet:GET-BUFFER-HANDLE("ttSalesRep"):SET-CALLBACK-PROCEDURE 
        ("AFTER-ROW-FILL", "postRepRowFill", THIS-PROCEDURE). 
    phDataSet:GET-BUFFER-HANDLE("ttSalesRep"):ATTACH-DATA-SOURCE 
        (DATA-SOURCE srcRep:HANDLE, "SalesRep.SalesRep,RepCode"). 
    phDataSet:GET-BUFFER-HANDLE("ttState"):ATTACH-DATA-SOURCE 
        (DATA-SOURCE srcState:HANDLE). 
    phDataSet:GET-BUFFER-HANDLE("ttDept"):ATTACH-DATA-SOURCE 
        (DATA-SOURCE srcDept:HANDLE). 
    RETURN phDataSet:ERROR. 
END FUNCTION. /* attachDataSet */ 

Nothing special happens here except mapping the SalesRep field in the database table to the RepCode field in the temp-table.

Note these facts about the HANDLE parameter to this function:


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095